﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace FlickrSL.Data
{
    //[XmlType("location")]
    public class Location : IXmlSerializable
    {
        public Dictionary<PlaceType, Place> Places { get; set; }

        //[XmlAttribute("latitude")]
        public Double Latitude { get; set; }

        //[XmlAttribute("longitude")]
        public Double Longitude { get; set; }

        //[XmlIgnore]
        public LocationAccuracy Accuracy { get; set; }

        //[XmlAttribute("accuracy")]
        //Int32 ILocationInfo.AccuracyValue
        //{
        //    get { return (Int32)this.Accuracy; }
        //    set { this.Accuracy = (LocationAccuracy)value; }
        //}

        //[XmlAttribute("context")]
        public Int32 Context { get; set; }

        //[XmlAttribute("place_id")]
        public String PlaceId { get; set; }

        //[XmlAttribute("woeid")]
        public Int32 WhereOnEarthId { get; set; }

        public Location()
        {
            this.Places = new Dictionary<PlaceType, Place>();
        }

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            if (!reader.IsStartElement("location"))
            {
                throw new InvalidOperationException("Expected Element 'location' Not Found");
            }

            this.Latitude = Double.Parse(reader.GetAttribute("latitude"));
            this.Longitude = Double.Parse(reader.GetAttribute("longitude"));
            this.Accuracy = (LocationAccuracy)Int32.Parse(reader.GetAttribute("accuracy"));
            this.Context = Int32.Parse(reader.GetAttribute("context"));
            this.PlaceId = reader.GetAttribute("place_id");
            if (!String.IsNullOrWhiteSpace(reader.GetAttribute("woeid")))
            {
                this.WhereOnEarthId = Int32.Parse(reader.GetAttribute("woeid"));
            }
            
            if (!reader.IsEmptyElement)
            {
                reader.ReadStartElement();

                reader.MoveToContent();
                while (reader.IsStartElement())
                {
                    Place p = new Place();
                    p.ReadXml(reader);
                    this.Places.Add(p.Type, p);
                    reader.MoveToContent();
                }

                reader.ReadEndElement();
            }
            else
            {
                reader.Skip();
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            // TODO
            throw new NotImplementedException();
        }
    }

    public class Place : IXmlSerializable
    {
        public PlaceType Type { get; set; }

        public String Id { get; set; }

        public String Name { get; set; }

        public Int32 WhereOnEarthId { get; set; }

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            this.Type = (PlaceType)Enum.Parse(typeof(PlaceType), reader.Name, true);

            this.Id = reader.GetAttribute("place_id");
            if (!String.IsNullOrWhiteSpace(reader.GetAttribute("woeid")))
            {
                this.WhereOnEarthId = Int32.Parse(reader.GetAttribute("woeid"));
            }

            if (reader.IsEmptyElement)
            {
                reader.ReadStartElement();
            }
            else
            {
                reader.ReadStartElement();
                this.Name = reader.ReadContentAsString();
                reader.ReadEndElement();
            }

            reader.MoveToContent();
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement(this.Type.ToString().ToLower());
            writer.WriteAttributeString("place_id", this.Id);
            writer.WriteAttributeString("woeid", this.WhereOnEarthId.ToString());
            writer.WriteEndElement();
        }
    }

    public enum PlaceType
    {
        Neighbourhood = 22,
        Locality = 7,
        Region = 8,
        Country = 12,
        Continent = 29
    }
}
